// 
// Copyright 2010 Classpath Pty Ltd <opensource@classpath.com.au>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 

using build

**
** Tests the `Adapter` class.
**
internal class AdapterTest : Test {

    **
    ** Stores an instance of `Adapter` for testing.
    **
    Adapter? adapter

    **
    ** Performs additional setup needed for `AdapterTest`.
    **
    override Void setup() {
        super.setup()
        adapter = AdapterTestClass()
    }

    **
    ** Cleans up additional setup needed for `AdapterTest`.
    **
    override Void teardown() {
        super.teardown()
        adapter = null
    }

    **
    ** Tests the `Adapter.sql` method with a `CreatedTable`.
    **
    Void testCreateTableSql() {
        adapter.sql(CreatedTable("table"))
        verify((adapter as AdapterTestClass).createTableWasCalled)
    }

    **
    ** Tests the `Adapter.sql` method with an `AlteredTable`.
    **
    Void testAlterTableSql() {
        adapter.sql(AlteredTable("table"))
        verify((adapter as AdapterTestClass).alterTableWasCalled)
    }

    **
    ** Tests the `Adapter.sql` method with a `DroppedTable`.
    **
    Void testDropTableSql() {
        adapter.sql(DroppedTable("table"))
        verify((adapter as AdapterTestClass).dropTableWasCalled)
    }

    **
    ** Tests the `Adapter.sql` method with an `ExecutedSql`.
    **
    Void testExecuteSql() {
        sql := adapter.sql(ExecutedSql("SQL"))
        verifyEq("SQL", sql)
        verify((adapter as AdapterTestClass).executeSqlWasCalled)
    }

    **
    ** Tests the `Adapter.sql` method with an `UnknownObject`.
    **
    Void testUnknownObjectSql() {
        verifyErr(Err#) {
            adapter.sql(UnknownTable("table"))
        }
    }

    **
    ** Tests the `Adapter.sql` method with a custom `KnownObject`.
    **
    Void testKnownObjectSql() {
        adapter.sql(KnownTable("table"))
        verify((adapter as AdapterTestClass).knownTableWasCalled)
    }

}

**
** Provides a simple implementation of `Adapter` for testing.
**
internal class AdapterTestClass : Adapter {

    **
    ** Records whether `Adapter.createTableSql` was called.
    **
    Bool createTableWasCalled := false

    **
    ** Records whether `Adapter.alterTableSql` was called.
    **
    Bool alterTableWasCalled := false

    **
    ** Records whether `Adapter.dropTableSql` was called.
    **
    Bool dropTableWasCalled := false

    **
    ** Records whether `Adapter.executeSql` was called.
    **
    Bool executeSqlWasCalled := false

    **
    ** Records whether `AdapterTestClass.knownTable` was called.
    **
    Bool knownTableWasCalled := false

    **
    ** Creates a new `AdapterTestClass` for testing.
    **
    new make() {
        handlers.add(KnownTable#, #knownTableSql)
    }

    **
    ** Provides a simple test implementation of `Adapter.createTableSql`.
    **
    override Str createTableSql(CreatedTable table) {
        createTableWasCalled = true
        return Str.defVal
    }

    **
    ** Provides a simple test implementation of `Adapter.alterTableSql`.
    **
    override Str alterTableSql(AlteredTable table) {
        alterTableWasCalled = true
        return Str.defVal
    }

    **
    ** Provides a simple test implementation of `Adapter.dropTableSql`.
    **
    override Str dropTableSql(DroppedTable table) {
        dropTableWasCalled = true
        return Str.defVal
    }

    **
    ** Provides a simple test implementation of `Adapter.executeSql`.
    **
    override Str executeSql(ExecutedSql sql) {
        executeSqlWasCalled = true
        return sql.sql
    }

    **
    ** Provides a simple test implementation of `Adapter.dbVersionSql`.
    **
    override Str dbVersionSql() {
        return Str.defVal
    }

    **
    ** Provides a simple test implementation of `Adapter.logMigrationSql`.
    **
    override Str logMigrationSql() {
        return Str.defVal
    }


    **
    ** Provides a simple test implementation of `AdapterTestClass.knownTableSql`.
    **
    Str knownTableSql(KnownTable table) {
        knownTableWasCalled = true
        return Str.defVal
    }
}

**
** Provides a subclass of `ModifiedTable` which does not have a registered handler.
**
internal class UnknownTable : ModifiedTable {

    **
    ** Creates a new `UnknownTable`.
    **
    new make(Str name) : super(name) {
    }

}

**
** Provides a subclass of `ModifiedTable` which does have a registered handler.
**
internal class KnownTable : ModifiedTable {

    **
    ** Creates a new `KnownTable`.
    **
    new make(Str name) : super(name) {
    }

}
